package com.pig4cloud.pigx.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.customize.i18n.util.MessageUtils;
import com.pig4cloud.pigx.common.data.resolver.ParamResolver;
import com.pig4cloud.pigx.system.constant.EmailTemplateTypeEnum;
import com.pig4cloud.pigx.system.dto.ArticleInformationDTO;
import com.pig4cloud.pigx.system.util.SendEmailUtil;
import com.pig4cloud.pigx.user.api.feign.RippleRemoteSystemService;
import com.pig4cloud.pigx.user.constant.RedisMessageType;
import com.pig4cloud.pigx.user.entity.User;
import com.pig4cloud.pigx.user.mapper.UserMapper;
import com.pig4cloud.pigx.user.service.EmailService;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import static com.pig4cloud.pigx.user.constant.I18nMessages.EMAIL_HAS_BEEN_REGISTERED;
import static com.pig4cloud.pigx.user.constant.I18nMessages.EMAIL_HAS_BEEN_SUBMITTED;
import static com.pig4cloud.pigx.user.constant.I18nMessages.EMAIL_TEMPLATE_TYPE_DOSE_NOT_EXIST;
import static com.pig4cloud.pigx.user.constant.I18nMessages.SEND_SUCCESSFULLY;


/**
 * @date:2022/8/8
 */
@Service
@RequiredArgsConstructor
public class EmailServiceImpl implements EmailService {

    /**
     * RedisKeyEnum
     */
    private final StringRedisTemplate stringRedisTemplate;
    /**
     * 平台用户
     */
    private final UserMapper userMapper;
    /**
     * ripple-system-biz的Feign
     */
    private final RippleRemoteSystemService rippleRemoteSystemService;

    /**
     * 发送邮箱工具类
     */
    private final SendEmailUtil sendEmailUtil;

    /**
     * 发送验证码
     *
     * @param user    邮箱信息
     * @param massage 邮件类型
     * @return
     */
    @Override
    public R sendEmail(User user, String massage) {

        // 邮箱格式验证
        R emailFormatVerification = sendEmailUtil.emailFormatVerification(user.getEmail());
        if (emailFormatVerification.getCode() != 0) {
            return emailFormatVerification;
        }

        R result = new R();
        //邮箱模板类型
        switch (massage) {
            case RedisMessageType.Customer_Registration:
                //客户邮箱注册
                result = sendVerificationCodeEmail(user, massage);
                break;
            case RedisMessageType.Customer_Modify_Email:
                //客户修改邮箱
                result = sendVerificationCodeEmail(user, massage);
                break;
            case RedisMessageType.Customer_Modify_MONEY_PASSWORD:
                //客户修改密码
                result = sendVerificationCodeEmail(user, massage);
                break;
            case RedisMessageType.BECOME_BROKER:
                //成为经纪人
                result = sendBecomeBrokerEmail(user, massage);
                break;
            case RedisMessageType.CUSTOMER_API_KEY_CREATE:
                //创建ApiKey
                result = sendVerificationCodeEmail(user, massage);
                break;
            default:
                //邮箱模板类型不存在
                return R.failed(MessageUtils.get(EMAIL_TEMPLATE_TYPE_DOSE_NOT_EXIST));
        }

        // 发送失败
        if (result.getCode() != 0) {
            return result;
        }


        return R.ok(MessageUtils.get(SEND_SUCCESSFULLY));
    }

    /**
     * 发送邮件(替换参数)
     *
     * @param titleCode       <${参数名}，参数>  邮件标题替换参数集合
     * @param textContentCode <${参数名}，参数>  内容邮件替换参数集合
     * @param email           收件人邮箱
     * @param massage
     * @param language        语言
     * @return
     */
    private R sendTrueEmail(Map<String, String> titleCode, Map<String, String> textContentCode,
                            String email, String massage, String language) {
        //获取文章中的邮件模板
        ArticleInformationDTO articleInformationDTO = new ArticleInformationDTO();
        //邮箱模板类型
        String articleTypeCode = EmailTemplateTypeEnum.findArticleTypeCodeByCode(massage);
        if (articleTypeCode == null) {
            //邮箱模板类型不存在
            return R.failed(MessageUtils.get(EMAIL_TEMPLATE_TYPE_DOSE_NOT_EXIST));
        }
        articleInformationDTO.setArticleTypeCode(articleTypeCode);
        //邮箱模板语言，当前语言为空则返回中文
        if (language != null && !language.isEmpty()) {
            articleInformationDTO.setLanguageId(language);
        } else {
            articleInformationDTO.setLanguageId("zh_CN");
        }
        return sendEmailUtil.sendEmail(titleCode, textContentCode, email, articleInformationDTO);

    }

    /**
     * 发送含有验证码的邮件
     *
     * @param user
     * @param massage
     * @return
     */
    private R sendVerificationCodeEmail(User user, String massage) {

        //判断邮箱是否重复发送
        String emailVerificationCode = stringRedisTemplate.opsForValue()
                .get(user.getEmail() + " massage = " + massage);
        if (emailVerificationCode != null && !emailVerificationCode.isEmpty()) {
            return R.failed(MessageUtils.get(EMAIL_HAS_BEEN_SUBMITTED));
        }

        //邮箱注册、修改邮箱 时判断用户是否注册
        if (RedisMessageType.Customer_Registration.equals(massage) ||
                RedisMessageType.Customer_Modify_Email.equals(massage)) {
            //查询数据库中邮箱是否存在
            Long email = userMapper.selectCount(new QueryWrapper<User>()
                    .eq("email", user.getEmail()));
            if (email > 0) {
                return R.failed(MessageUtils.get(EMAIL_HAS_BEEN_REGISTERED));
            }

        }

        // 六位随机数验证码
        String code = String.valueOf((int) ((Math.random() * 9 + 1) * 100000));

        // 邮件内容中替换的参数
        Map<String, String> textContentCode = new HashMap<>();
        textContentCode.put("${code}", code);

        // 发送验证码邮件
        R r = sendTrueEmail(null, textContentCode, user.getEmail(), massage, user.getLanguageCode());

        if (r.getCode() == 1) {
            return r;
        }
        //向redis里存入数据和设置缓存时间
        stringRedisTemplate.opsForValue().set(
                user.getEmail() + " massage = " + massage,
                code, 60 * 3, TimeUnit.SECONDS);

        return R.ok(MessageUtils.get(SEND_SUCCESSFULLY));
    }


    private R sendBecomeBrokerEmail(User user, String massage) {
        // 邮件内容中替换的参数
        Map<String, String> textContentCode = new HashMap<>();
        // 用户名
        textContentCode.put("${userName}", user.getUserName());
        // 密码
        textContentCode.put("${password}", user.getPassword());
        // 经纪人后台管理地址
        textContentCode.put("${BrokerBackgroundManagementUrl}", ParamResolver.getStr("BROKER_BACKGROUND_MANAGEMENT_URL"));

        // 发送验证码邮件
        R r = sendTrueEmail(null, textContentCode, user.getEmail(), massage, user.getLanguageCode());

        if (r.getCode() == 1) {
            return r;
        }
        return R.ok(MessageUtils.get(SEND_SUCCESSFULLY));
    }

}
